package com.chdwmp.product.utils;

import cn.hutool.core.util.ObjectUtil;
import com.chdwmp.product.constant.CommonConstants;
import com.chdwmp.product.constant.DateConstants;
import org.apache.commons.lang3.StringUtils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;


/**
 * @author 姬海威 [haiwei.ji@tigermed.net]
 * @Date 2017-6-13 16:57
 */
public class DateUtils {

    /**
     * 字符串转换成日期
     */
    public static Date stringToDate(String date, String formatStr) throws Exception {
        DateFormat df = new SimpleDateFormat(formatStr);
        return (Date) df.parseObject(date);
    }

    /**
     * 字符串转换成日期(yyyy-MM-dd)
     */
    public static Date stringToDate(String date) throws Exception {
        DateFormat df = new SimpleDateFormat(DateConstants.FORMAT_DATE);
        return (Date) df.parseObject(date);
    }

    /**
     * 日期转换成字符串
     */
    public static String dateToString(Date date, String formatStr) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatStr);
        return sdf.format(date);
    }

    /**
     * 日期转换成字符串(yyyy-MM-dd)
     */
    public static String dateToString(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(DateConstants.FORMAT_DATE);
        return sdf.format(date);
    }

    /**
     * 计算两个日期之间相差的天数
     */
    public static int daysBetween(Date smallDate, Date bigDate) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat(DateConstants.FORMAT_DATE);
        smallDate = sdf.parse(sdf.format(smallDate));
        bigDate = sdf.parse(sdf.format(bigDate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smallDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bigDate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / DateConstants.DAY_MILLI_SECONDS;

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 获取一定分钟后的时间
     */
    public static Date addMinute(Date date, int minuteCount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minuteCount);
        return calendar.getTime();
    }

    /**
     * 获取一定小时后的时间
     */
    public static Date addHour(Date date, int hourCount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hourCount);
        return calendar.getTime();
    }

    /**
     * 获取一定月份后的时间
     */
    public static Date addMonth(Date date, int monthCount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, monthCount);
        return calendar.getTime();
    }

    /**
     * 获取一定年份后的时间
     */
    public static Date addYear(Date date, int yearCount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, yearCount);
        return calendar.getTime();
    }

    /**
     * 时间戳转化为指定格式字符串
     */
    public static String formatLongDate(Long time, String formatStr) throws Exception {
        Timestamp ts = new Timestamp(time);
        DateFormat sdf = new SimpleDateFormat(formatStr);
        return sdf.format(ts);
    }

    /**
     * @Description: 获取本周日日期
     */
    public static String getSundayOfThisWeek() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateConstants.FORMAT_DATE);
        Calendar c = Calendar.getInstance();
        int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (day_of_week == 0)
            day_of_week = 7;
        c.add(Calendar.DATE, -day_of_week + 7);
        return simpleDateFormat.format(c.getTime());
    }

    /**
     * @Description: 得到本月第一天
     */
    public static String getCurrentMonthFirstDay() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateConstants.FORMAT_DATE);
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        return simpleDateFormat.format(c.getTime());
    }

    /**
     * @Description: 得到本月最后一天
     */
    public static String getCurrentMonthLastDay() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateConstants.FORMAT_DATE);
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return simpleDateFormat.format(c.getTime());
    }

    /**
     * @Description: 得到当前日期
     */
    public static String currentDate() {
        SimpleDateFormat sdf = new SimpleDateFormat(DateConstants.FORMAT_DATE);
        return sdf.format(new Date());
    }

    /**
     * @Description: 得到当前日期
     */
    public static String currentDateForYearMonth() {
        SimpleDateFormat sdf = new SimpleDateFormat(DateConstants.FORMAT_YEAR_MONTH);
        return sdf.format(new Date());
    }

    /**
     * @Description: 得到当前日期(yyyyMMdd)
     */
    public static String currentDateForYearMonthDay() {
        SimpleDateFormat sdf = new SimpleDateFormat(DateConstants.FORMAT_YEAR_MONTH_DAY);
        return sdf.format(new Date());
    }

    /**
     * @Description: 得到当前时间
     */
    public static String currentDateTime() {
        SimpleDateFormat sdf = new SimpleDateFormat(DateConstants.FORMAT_DATE_TIME);
        return sdf.format(new Date());
    }

    /**
     * 比较一个时间是否在指定的时间段内
     */
    public static boolean belongCalendar(Date time, Date from, Date to) {
        Calendar date = Calendar.getInstance();
        date.setTime(time);

        Calendar after = Calendar.getInstance();
        after.setTime(from);

        Calendar before = Calendar.getInstance();
        before.setTime(to);
        return date.compareTo(after) >= 0 && date.compareTo(before) <= 0;
    }

    /**
     * 获取当前时间的年月值
     */
    public static String getCurrentYearAndMonth() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        return String.valueOf(year) + String.valueOf(month);
    }

    /**
     * 获取当前时间的年份
     */
    public static String getCurrentYear() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        return String.valueOf(year);
    }

    /**
     * 获取当前时间的年月值[月份固定为两位数]
     */
    public static String getCurrentYearAndMonth2() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        if (month < 10) {
            return String.valueOf(year) + "0" + String.valueOf(month);
        }
        return String.valueOf(year) + String.valueOf(month);
    }

    /**
     * 时间戳说明：
     * 刚刚：1分钟以内；
     * m分钟前：1分钟（含）以上、1小时以内；
     * h小时前：1小时（含）以上、今天；
     * d天前：按日历1天（含）以上、7天以内；
     * M月D日：按日历7天（含）以上、本年；
     * Y年M月D日：按日历今年以前
     */
    @SuppressWarnings("RedundantCast")
    public static String formatTimeStamp(String dateString) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (StringUtils.isNotEmpty(dateString)) {
            dateString = dateString.length() > 19 ? dateString.substring(0, 19) : dateString;

            Date formatDate = null;
            try {
                formatDate = simpleDateFormat.parse(dateString);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Long formatDateTime = formatDate.getTime();
            Long currentDateTime = System.currentTimeMillis();

            int second = (int) ((currentDateTime - formatDateTime) / CommonConstants.TimeStamp.MILLISECONDS);

            if (second < CommonConstants.TimeStamp.MINUTES) {
                dateString = "刚刚";
            } else if (CommonConstants.TimeStamp.MINUTES <= second && second < CommonConstants.TimeStamp.SECONDS) {
                dateString = (int) second / CommonConstants.TimeStamp.MINUTES + "分钟前";
            } else if (CommonConstants.TimeStamp.SECONDS <= second && second < CommonConstants.TimeStamp.SECONDS * CommonConstants.TimeStamp.HOURS) {
                dateString = (int) second / CommonConstants.TimeStamp.SECONDS + "小时前";
            } else if (CommonConstants.TimeStamp.SECONDS * CommonConstants.TimeStamp.HOURS <= second && second < CommonConstants.TimeStamp.SECONDS * CommonConstants.TimeStamp.HOURS * CommonConstants.TimeStamp.WEEKS) {
                dateString = (int) second / (CommonConstants.TimeStamp.SECONDS * CommonConstants.TimeStamp.HOURS) + "天前";
            } else if (CommonConstants.TimeStamp.SECONDS * CommonConstants.TimeStamp.HOURS * CommonConstants.TimeStamp.WEEKS <= second) {
                String formatYear = dateString.substring(0, 4);
                String currentYear = simpleDateFormat.format(new Date()).substring(0, 4);

                if (formatYear.equals(currentYear)) {
                    dateString = dateString.substring(5, 10);
                } else {
                    dateString = dateString.substring(0, 10);
                }
            }
        }
        return dateString;
    }

    /**
     * dateString:事件时间
     * 时间戳说明：
     * 刚刚：1分钟以内；
     * m分钟前：当天24点之前、1分钟以上并且m分钟前
     * h小时前：当天24点之前并且1小时后n小时前
     * 昨天 h时m分： 当天24点之后并且明天24点前
     * M月D日：按日历1天（含）以上、本年；
     * Y年M月D日：按日历今年以前
     */
    @SuppressWarnings("RedundantCast")
    public static String formatTimeLikeWeiboStamp(String dateString) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (StringUtils.isNotEmpty(dateString)) {
            dateString = dateString.length() > 19 ? dateString.substring(0, 19) : dateString;
            //当前yyyy、-MM-dd
            String currentYear = simpleDateFormat.format(new Date()).substring(0, 4);
            String currentMonthAndDay = simpleDateFormat.format(new Date()).substring(5, 10);
            //传入时间的yyyy、-MM-dd、HH:mm
            String formatYear = dateString.substring(0, 4);
            String formatMonthAndDay = dateString.substring(5, 10);
            String formatHourMinute = dateString.substring(11, 16);
            //月、日
            String dateStrMonth = formatMonthAndDay.substring(0, 2);
            String dateStrDay = formatMonthAndDay.substring(3, 5);
            //例如2018-01-01转化成2018-1-1
            if ("0".equals(dateStrMonth.substring(0, 1))) {
                dateStrMonth = dateStrMonth.substring(1, 2);
            }
            if ("0".equals(dateStrDay.substring(0, 1))) {
                dateStrDay = dateStrDay.substring(1, 2);
            }
            Date formatDate = null;
            try {
                formatDate = simpleDateFormat.parse(dateString);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            Long formatDateTime = formatDate.getTime();
            Long currentDateTime = System.currentTimeMillis();

            if (currentYear.equals(formatYear)) {
                int second = (int) ((currentDateTime - formatDateTime) / CommonConstants.TimeStamp.MILLISECONDS);
                if (currentMonthAndDay.equals(formatMonthAndDay)) {
                    if (second < CommonConstants.TimeStamp.MINUTES) {
                        dateString = "刚刚";
                    } else if (CommonConstants.TimeStamp.MINUTES <= second && second < CommonConstants.TimeStamp.SECONDS) {
                        dateString = (int) second / CommonConstants.TimeStamp.MINUTES + "分钟前";
                    } else if (CommonConstants.TimeStamp.SECONDS <= second && second < CommonConstants.TimeStamp.SECONDS * CommonConstants.TimeStamp.HOURS) {
                        dateString = (int) second / CommonConstants.TimeStamp.SECONDS + "小时前";
                    }
                } else {
                    String formatMonthAndDay2 = formatMonthAndDay.replace("-", "");
                    String currentMonthAndDay2 = currentMonthAndDay.replace("-", "");
                    //相差一天
                    if (Integer.valueOf(currentMonthAndDay2) - Integer.valueOf(formatMonthAndDay2) == 1) {
                        dateString = "昨天" + formatHourMinute;
                    } else {
                        return dateStrMonth + "-" + dateStrDay;
                    }
                }
            } else {
                dateString = formatYear + "-" + dateStrMonth + "-" + dateStrDay;
            }
        }
        return dateString;
    }

    /**
     * 指定数字转化成日期
     * 如10-周一上午 11-周一下午
     * 20-周二上午 21周二下午 ....第一位数字代表周X 第二位数字0-上午 1-下午
     */
    public static String number2DateString(String numberDate) {
        StringBuffer result = new StringBuffer();
        if (StringUtils.isNotEmpty(numberDate) && numberDate.length() == 2) {
            String week = numberDate.split("")[0];
            String noon = numberDate.split("")[1];

            result.append(formatWeek(week)).append(formatNoon(noon));
        }

        return result.toString();
    }

    private static String formatWeek(String week) {
        switch (week) {
            case "1":
                return "周一";
            case "2":
                return "周二";
            case "3":
                return "周三";
            case "4":
                return "周四";
            case "5":
                return "周五";
            case "6":
                return "周六";
            case "7":
                return "周日";
        }
        return null;
    }

    public static String formatForWeek(String week) {
        switch (week) {
            case "1":
                return "7";
            case "2":
                return "1";
            case "3":
                return "2";
            case "4":
                return "3";
            case "5":
                return "4";
            case "6":
                return "5";
            case "7":
                return "6";
        }
        return null;
    }

    private static String formatNoon(String noon) {
        switch (noon) {
            case "0":
                return "上午";
            case "1":
                return "下午";
        }
        return null;
    }

    /**
     * 时间戳转化成时间格式"yyyy-MM-dd HH:mm:ss"
     *
     * @param timeStamp
     */
    public static String timeStamp2DateStr(String timeStamp) {
        long timeStamp2Long = Long.valueOf(timeStamp);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sd = sdf.format(new Date(Long.parseLong(String.valueOf(timeStamp))));
        return sd;
    }


    public static String secondToHhMm(Integer secondInt) {
        StringBuilder strb = new StringBuilder();
        Integer minute = secondInt / 60;
        Integer remainingSecond = secondInt % 60;
        if (minute < 10) {
            strb.append("0").append(minute.toString());
        } else {
            strb.append(minute.toString());
        }
        strb.append(":");
        if (remainingSecond < 10) {
            strb.append("0").append(remainingSecond.toString());
        } else {
            strb.append(remainingSecond.toString());
        }
        return strb.toString();
    }



    /**
     * @param lastTime 最近一次时间
     * @param currentTime 上次时间
     * @return
     */
    public static int dayNum(LocalDate lastTime, LocalDate currentTime) {
        if (ObjectUtil.isEmpty(lastTime) || ObjectUtil.isEmpty(currentTime)){
            return 0;
        }
        long delivery_days = currentTime.until(lastTime, ChronoUnit.DAYS);
        return (int) delivery_days;
    }

    /**
     * yyyyMMddHHmmss-->yyyy-MM-dd HH:mm:ss
     **/
    public static Date yyyyMMddHHmmssToDate(String date) throws Exception {
        String reg = "(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})";
        date = date.replaceAll(reg, "$1-$2-$3 $4:$5:$6");
        return stringToDate(date,DateConstants.FORMAT_DATE_TIME);
    }

}
